/*
 ------------------------------------------------------------------------------
 Copyright (C) 2013 Eternal Games.

 This file is part of the GLQuake source code.

 The GLQuake source code is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or (at your
 option) any later version.

 The GLQuake source code is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 more details.

 You should have received a copy of the GNU General Public License along with
 the GLQuake source code; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 ------------------------------------------------------------------------------
*/


//
// fileSystem.h - framework used by dynamic-link libraries
//


#ifndef __FRAMEWORK_FILESYSTEM_H__
#define __FRAMEWORK_FILESYSTEM_H__


/*
 ==============================================================================

 File System:

 ==============================================================================
*/

#define	MAX_PATH_LENGTH				256			// Max length of a file system path

#define MAX_PACK_FILES				128			// Max number of pack files loaded

typedef int							fileHandle_t;

enum fsMode_t {
	FS_READ,
	FS_WRITE,
	FS_APPEND
};

enum fsOrigin_t {
	FS_SEEK_SET,
	FS_SEEK_CUR,
	FS_SEEK_END
};

enum findFile_t {
	FIND_NO,
	FIND_PACK,
	FIND_DIRECTORY
};

// Functions exported by the engine
struct glqFileSystem_t {
	// Reads data from a file, properly handling partial reads.
	// Returns the number of bytes read.
	int						(*Read)(fileHandle_t f, void *buffer, int size);

	// Writes data to a file, properly handling partial writes.
	// Returns the number of bytes written.
	int						(*Write)(fileHandle_t f, const void *buffer, int size);

	// Writes formatted text to a file.
	// Returns the number of characters written.
	int						(*Printf)(fileHandle_t f, const char *fmt, ...);

	// Returns the offset in a file
	int						(*Tell)(fileHandle_t f);

	// Seeks on a file
	void					(*Seek)(fileHandle_t f, int offset, fsOrigin_t origin);

	// Opens the given file for reading, writing, or appending. Will create any
	// needed subdirectories.
	// Returns file size, or -1 if the file wasn't found or an error occurred.
	int						(*OpenFile)(const char *name, fsMode_t mode, fileHandle_t *f);

	// Closes the given file
	void					(*CloseFile)(fileHandle_t f);

	// Removes the given file
	bool					(*RemoveFile)(const char *name);

	// Returns true if the given file exists in the current game directory.
	// This is to determine if writing a file will cause any overwrites.
	bool					(*FileExists)(const char *name);

	// Looks for a file in the search paths.
	// Returns file availability and optionally sets the source path if found.
	findFile_t				(*FindFile)(const char *name, char sourcePath[MAX_PATH_LENGTH]);

	// Reads a complete file.
	// Returns file size, or -1 if the file wasn't found or an error occurred.
	// A NULL buffer will just return the file size without loading as a quick
	// check for existance (-1 == not present).
	// Appends a trailing 0, so string operations are always safe.
	int						(*ReadFile)(const char *name, void **buffer);

	// Frees the memory allocated by ReadFile
	void					(*FreeFile)(const void *buffer);

	// Writes a complete file. Will create any needed subdirectories.
	// Returns true if the file was written.
	bool					(*WriteFile)(const char *name, const void *buffer, int size);

	// Extracts the given dynamic library from a pack file and sets the fully
	// qualified path to the extracted file (appending suffix and extension
	// appropriate for the underlying platform).
	// Returns false if the dynamic library could not be found or extracted.
	bool					(*ExtractLibrary)(const char *baseName, char libPath[MAX_PATH_LENGTH]);

	// Returns a list of files and subdirectories that match the given
	// extension (which must include a leading '.' and must not contain
	// wildcards).
	// If extension is NULL, all the files will be returned and all the
	// subdirectories ignored.
	// If extension is "/", all the subdirectories will be returned and all the
	// files ignored.
	// The returned list can optionally be sorted.
	const char **			(*ListFiles)(const char *path, const char *extension, bool sort, int *numFiles);

	// Returns a list of files and subdirectories that match the given filter.
	// The returned list can optionally be sorted.
	const char **			(*ListFilteredFiles)(const char *filter, bool sort, int *numFiles);

	// Frees the memory allocated by ListFiles and ListFilteredFiles
	void					(*FreeFileList)(const char **fileList);
};


#endif	// __FRAMEWORK_FILESYSTEM_H__